package cn.wx.scholar.neo4j.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.neo4j.ogm.model.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import cn.wx.common.persistence.exception.MyException;
import cn.wx.common.persistence.web.ResponseCode;
import cn.wx.scholar.core.entity.Paper;
import cn.wx.scholar.core.entity.qo.PaperQ;
import cn.wx.scholar.core.service.PaperService;
import cn.wx.scholar.neo4j.entity.Neo4jPaper;
import cn.wx.scholar.neo4j.entity.dto.FosPaperDTO;
import cn.wx.scholar.neo4j.entity.dto.PaperDTO;
import cn.wx.scholar.neo4j.entity.qo.Neo4jPaperQ;
import cn.wx.scholar.neo4j.repository.PaperRepository;
import cn.wx.scholar.tool.neo4j.N2OUtils;
import cn.wx.scholar.tool.neo4j.Neo4jQueryTools;

@Service
public class Neo4jPaperService {
	
	Logger logger = LoggerFactory.getLogger(Neo4jPaperService.class);
	
	@Autowired
    private PaperRepository paperRepositiory;
	
	@Autowired
	private PaperService paperService;
	
	/**
	 * 分页查询论文
	 * @param neo4jPaperQ
	 * @return
	 */
	public Page<Neo4jPaper> getPapersByExpertId(Neo4jPaperQ neo4jPaperQ){
		
		/**
		 * 必要参数
		 */
		if(neo4jPaperQ == null || neo4jPaperQ.getExpertId() == null) {
			throw new MyException(ResponseCode.PARAMETER_REQUIRED);
		}
		
		
    	Page<Neo4jPaper> pages = paperRepositiory.getPapersByExpertId(
    			neo4jPaperQ.getExpertId(),
    			neo4jPaperQ.getDocType(),
    			PageRequest.of(neo4jPaperQ.getPageSkip(), neo4jPaperQ.getPageSize()));
    	
    	if(pages!=null && pages.getContent()!=null) {
			
			List<Long> fIds = new ArrayList<>();
			
			for(Neo4jPaper mpr : pages) {
				fIds.add(mpr.getfId());
			}
			
			if(fIds.size() > 0) {
				PaperQ nQ = new PaperQ();
				nQ.setfIds(fIds);
				
				List<Paper> papers = paperService.queryList(nQ);
				
				
				Map<Long,Paper> cPaperMap = null;
				
				if(papers != null && papers.size() > 0) {
					cPaperMap = new HashMap<>();
					for(Paper n : papers) {
						cPaperMap.put(n.getfId(), n);
					}
				}
				
				if(cPaperMap != null) {
					for(Neo4jPaper ew_ : pages.getContent()) {
						covetMysqlToNeo4j(ew_, cPaperMap.get(ew_.getfId()),false);
					}
				}
				
			}
			
			
    	}
    	
    	return pages;
	}
	
	/**
	 * 把mysql 的数据放到 neo4j中 
	 */
	private void covetMysqlToNeo4j(Neo4jPaper nO,Paper mO,Boolean isDetails) {
		
		if(mO == null) {
			logger.info("this data have no mysqlRecond :"+ nO.getfId());
			return;
		}
		
		nO.setTitle(mO.getTitle());
		nO.setAuthors(mO.getfAuthors());
		
		String[] su = mO.getUrl_();
		
		if(su != null && su.length >0 ) {
			nO.setUrl(su[0]);
		}
		
		if(isDetails) {
			nO.setfAbstract(mO.getfAbstract());
			nO.setUrls(su);
		}
	}
	
	
	public Neo4jPaper findPaperDetailById(Long id) {
		return paperRepositiory.findPaperDetailById(id);
	}
	
	/**
	 * 按领域关键词统计论文数量
	 */
	public Object statisticsPaperByPos(String fosName) {
		
		if(StringUtils.isBlank(fosName)){
			throw new MyException(ResponseCode.PARAMETER_REQUIRED);
		}

		/**
		 * 构建全文索引的参数
		 */
		final String q = Neo4jQueryTools.basicIndex(fosName);
		
		Result result = paperRepositiory.statisticsPaperByPos(q);
		
		if(result == null) {
			return null;
		}

		return result.queryResults();
	}
	
	/**
	 * 统计某个专家对于每一个fos关键词历年的论文数量（鼠标点击某年，可以显示某年论文数量）
	 * @param fos
	 * @param id
	 * @return
	 */
	public Object statisticsPaperByExpertPos(List<String> fosName, Long expertId) {
		
		/**
		 * 先根据领域的名称查询领域的fId
		 */
		if(fosName == null || fosName.size() == 0) {
			throw new MyException(ResponseCode.PARAMETER_REQUIRED);
		}
		
		/**
		 * 调用neo4j，查询结果集
		 */
		Result result = paperRepositiory.statisticsPaperByExpertPos(expertId);
		
		List<PaperDTO> pds = N2OUtils.covetResultToDTO(result, PaperDTO.class);
		
		Map<String,FosPaperDTO> map = new HashMap<>();
		
		if(pds != null) {
			
			for(PaperDTO p : pds) {
				List<String> pfos = p.getFos_();
				if(pfos == null || pfos.size() == 0){
					continue;
				}
				
				for(String si : fosName){
					final String t = si.replaceAll(" ", "___");
					if(pfos.contains(t.toLowerCase())) {
						final String mkey = si + "--" + p.getYear();
						FosPaperDTO fd = map.get(mkey);
						if(fd == null) {
							fd = new FosPaperDTO(si, p.getYear());
						}
						fd.flyPnum();
						map.put(mkey, fd);
					}
				}
			}
		}

		return map.values();
	}
	
	/**
	 * 查询一个论文的信息深度为 1
	 * @param id
	 * @return
	 */
	public Neo4jPaper findOnePaper(Long id) {
		/**
		 * 从知识图谱中查询
		 */

		Neo4jPaper np = paperRepositiory.findPaperDetailById(id);
		
		if(np != null) {
			
			/**
			 * 从数据库中查出paper
			 */
			Paper paper = paperService.queryOneByFId(np.getfId());
			
			if(paper != null) {
				covetMysqlToNeo4j(np, paper,true);
			}
			
		}
		return np;
	}
}
